using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;
using MD5;

namespace Commons.Utils
{
	public class IOHelper
	{
		public static void Copy(Stream input, Stream output)
		{
			byte[] buffer = new byte[4096];

			int size = input.Read(buffer, 0, buffer.Length);
			while (size > 0)
			{
				output.Write(buffer, 0, size);

				size = input.Read(buffer, 0, buffer.Length);
			}
		}

		public static string ReadText(Stream input, Encoding encoding)
		{
			using (StreamReader reader = new StreamReader(input, encoding))
			{
				return reader.ReadToEnd();
			}
		}

		public static byte[] ReadToEnd(System.IO.Stream stream)
		{
			long originalPosition = 0;
			
			if(stream.CanSeek)
			{
				originalPosition = stream.Position;
				stream.Position = 0;
			}
			
			try
			{
				byte[] readBuffer = new byte[4096];
				
				int totalBytesRead = 0;
				int bytesRead;
				
				while ((bytesRead = stream.Read(readBuffer, totalBytesRead, readBuffer.Length - totalBytesRead)) > 0)
				{
					totalBytesRead += bytesRead;
					
					if (totalBytesRead == readBuffer.Length)
					{
						int nextByte = stream.ReadByte();
						if (nextByte != -1)
						{
							byte[] temp = new byte[readBuffer.Length * 2];
							Buffer.BlockCopy(readBuffer, 0, temp, 0, readBuffer.Length);
							Buffer.SetByte(temp, totalBytesRead, (byte)nextByte);
							readBuffer = temp;
							totalBytesRead++;
						}
					}
				}
				
				byte[] buffer = readBuffer;
				if (readBuffer.Length != totalBytesRead)
				{
					buffer = new byte[totalBytesRead];
					Buffer.BlockCopy(readBuffer, 0, buffer, 0, totalBytesRead);
				}
				return buffer;
			}
			finally
			{
				if(stream.CanSeek)
				{
					stream.Position = originalPosition; 
				}
			}
		}

		public static string ComputeMd5(Stream input)
		{
			byte[] buffer = ReadToEnd (input);
			MD5Object md5 = new MD5Object();
			md5.ValueAsByte = buffer;
			string hash = md5.FingerPrint;

			Debug.Log ("hash = " + hash);

			return hash;
		}
	}
}

